package com.redepronik.negosysres.invfac.controller;

import static com.redepronik.negosys.utils.Utils.parametro;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.context.RequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.redepronik.negosys.invfac.entity.Detalleegreso;
import com.redepronik.negosys.invfac.entity.Egreso;
import com.redepronik.negosys.invfac.entity.Entrada;
import com.redepronik.negosys.invfac.entity.Local;
import com.redepronik.negosys.invfac.entity.Producto;
import com.redepronik.negosys.invfac.entityAux.CantidadFactura;
import com.redepronik.negosys.invfac.entityAux.FacturaReporte;
import com.redepronik.negosys.invfac.service.EgresoService;
import com.redepronik.negosys.invfac.service.MotivoBajaService;
import com.redepronik.negosys.invfac.service.ProductoService;
import com.redepronik.negosys.invfac.service.TipoDocumentoService;
import com.redepronik.negosys.rrhh.service.ClienteService;
import com.redepronik.negosysres.invfac.report.EgresoReport;

@Controller
@Scope("session")
public class DevolucionBean implements Serializable {

	private static final long serialVersionUID = 1L;

	@Autowired
	private EgresoService egresoService;

	@Autowired
	private ProductoService productoService;

	@Autowired
	private ClienteService clienteService;

	@Autowired
	private TipoDocumentoService tipoDocumentoService;

	@Autowired
	private MotivoBajaService motivoBajaService;

	@Autowired
	private EgresoReport egresoReport;

	private Egreso egreso;
	private String compModifica;

	private Producto producto;

	private List<FacturaReporte> listaFacturaReporteDevolucion;
	private List<FacturaReporte> facturaReportes;
	private FacturaReporte facturaReporte;
	private CantidadFactura cantidadFacturaCalculos;
	private CantidadFactura cantidadFacturaPresentar;

	private Integer cantidad;

	private boolean factura;

	public DevolucionBean() {
		producto = new Producto();
		listaFacturaReporteDevolucion = new ArrayList<FacturaReporte>();
		facturaReportes = new ArrayList<FacturaReporte>();
		facturaReporte = new FacturaReporte();
		cantidadFacturaCalculos = new CantidadFactura();
		cantidadFacturaPresentar = new CantidadFactura();
	}

	public void cancelar() {
		facturaReporte = new FacturaReporte();
	}

	public void cancelarTodo() {
		xxx();
		facturaReportes = new ArrayList<FacturaReporte>();
		listaFacturaReporteDevolucion = new ArrayList<FacturaReporte>();
		cantidadFacturaCalculos = new CantidadFactura();
		compModifica = null;
	}

	public boolean comprobar() {
		RequestContext context = RequestContext.getCurrentInstance();
		boolean bn = true;
		if (egreso.getDetalleegresos().isEmpty()) {
			bn = false;
			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_ERROR,
					"ERROR", "DEBE INGRESAR DETALLES"));
		}
		if (bn)
			context.addCallbackParam("error", true);
		else
			context.addCallbackParam("error", false);

		return bn;
	}

	public void convertirDevolucion(Egreso egreso) {
		egreso = egresoService.obtenerPorEgresoId(egreso.getEgresoid());

		int tipoDocumentoId = 0;
		if (egreso.getTipodocumento().getTipodocumentoid() == 1) {
			factura = true;
			tipoDocumentoId = 10;
		} else if (egreso.getTipodocumento().getTipodocumentoid() == 8) {
			factura = false;
			tipoDocumentoId = 4;
		}

		compModifica = egreso.getCodigodocumento();
		this.egreso = egresoService.duplicarEgreso(egreso, tipoDocumentoId);
		this.egreso.setPadre(egreso.getEgresoid());
		this.egreso.setFechainicio(new Timestamp(new Date().getTime()));
		this.egreso.setDetalleegresos(new ArrayList<Detalleegreso>());

		if (factura)
			this.egreso.setCodigodocumento(parametro
					.getCodigoestablecimiento()
					.concat("-")
					.concat(parametro
							.getCodigoemision()
							.concat("-")
							.concat(String.format("%09d",
									parametro.getSecuenciacredito() + 1))));
		else
			this.egreso.setCodigodocumento(tipoDocumentoService
					.obtenerPorId(4)
					.getAbreviatura()
					.concat("-")
					.concat(String.format("%010d",
							parametro.getSecuenciadevolucion() + 1)));

		for (Detalleegreso detalleEgreso : egreso.getDetalleegresos())
			listaFacturaReporteDevolucion.add(egresoService.asignar(
					detalleEgreso, null, egreso.getTipodocumento()
							.getTipodocumentoid()));

	}

	public void eliminarDetalle(ActionEvent actionEvent) {
		int posicion = egresoService.posicion(facturaReporte,
				egreso.getDetalleegresos(), factura);
		if (posicion >= 0) {
			Detalleegreso de = egreso.getDetalleegresos().get(posicion);
			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_INFO,
					"ELIMINÓ DETALLE", "Elimino: " + de.getProducto().getEan()));
			egreso.removeDetalleegreso(de);
			if (factura)
				cantidadFacturaCalculos = egresoService
						.calcularCantidadFactura(cantidadFacturaCalculos,
								facturaReporte, "subtract");
			else
				cantidadFacturaCalculos = egresoService
						.calcularCantidadNotaEntrega(cantidadFacturaCalculos,
								facturaReporte, "subtract");

			facturaReportes.remove(facturaReporte);
			cancelar();
		}
	}

	public Integer getCantidad() {
		return cantidad;
	}

	public CantidadFactura getCantidadFacturaCalculos() {
		return cantidadFacturaCalculos;
	}

	public CantidadFactura getCantidadFacturaPresentar() {
		return egresoService.redondearCantidadFactura(cantidadFacturaPresentar,
				cantidadFacturaCalculos);
	}

	public String getCompModifica() {
		return compModifica;
	}

	public Egreso getEgreso() {
		return egreso;
	}

	public FacturaReporte getFacturaReporte() {
		return facturaReporte;
	}

	public List<FacturaReporte> getFacturaReportes() {
		return facturaReportes;
	}

	public List<FacturaReporte> getListaFacturaReporteDevolucion() {
		return listaFacturaReporteDevolucion;
	}

	public Producto getProducto() {
		return producto;
	}

	public void insertarDetalle(ActionEvent actionEvent) {
		producto = productoService.obtenerPorProductoId(facturaReporte
				.getProductoId());

		if (cantidad <= facturaReporte.getCantidad() && cantidad > 0) {
			Detalleegreso detalleEgreso = new Detalleegreso();

			detalleEgreso.setProducto(producto);

			FacturaReporte fr = new FacturaReporte();

			fr.setPrecioId(facturaReporte.getPrecioId());
			fr.setCantidad(cantidad);
			fr.setPrecioUnitVenta(facturaReporte.getPrecioUnitVenta());
			fr.setPromocion(facturaReporte.isPromocion());

			fr = egresoService.asignar(detalleEgreso, fr, egreso
					.getTipodocumento().getTipodocumentoid());

			detalleEgreso.setCantidad(fr.getCantidad());
			detalleEgreso.setPreciocosto(producto.getPrecio());
			detalleEgreso.setIva(producto.getIva());
			detalleEgreso.setPrecioventa(fr.getPrecioUnitVenta());
			detalleEgreso.setPromocion(fr.isPromocion());
			detalleEgreso.setEliminar(fr.isEliminar());

			if (factura)
				cantidadFacturaCalculos = egresoService
						.calcularCantidadFactura(cantidadFacturaCalculos, fr,
								"add");
			else
				cantidadFacturaCalculos = egresoService
						.calcularCantidadNotaEntrega(cantidadFacturaCalculos,
								fr, "add");

			facturaReportes.add(fr);
			egreso.addDetalleegreso(detalleEgreso);
			listaFacturaReporteDevolucion.remove(facturaReporte);

			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_INFO,
					"INSERTÓ DETALLE", "INSERTO: " + producto.getEan()));
			cancelar();
			cantidad = null;
			producto = new Producto();
		} else
			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_ERROR,
					"ERROR", "INGRESE UNA CANTIDAD MENOR A LA VENDIDA: "
							+ facturaReporte.getCantidad()
							+ " O MAYOR QUE CERO"));
	}

	public void insertarOrActualizar(ActionEvent actionEvent) {
		if (comprobar()) {
			egresoService.insertar(egreso, null);
			egresoService.devolucion(egreso);
			Egreso e = egresoService.obtenerPorEgresoId(egreso.getPadre());
			e.setDevolucion(true);
			egresoService.actualizar(e, null);
			presentaMensaje(new FacesMessage(FacesMessage.SEVERITY_INFO,
					"INSERTÓ", "DEVOLUCION: " + egreso.getCodigodocumento()));
			cancelarTodo();
		}

	}

	private void presentaMensaje(FacesMessage message) {
		FacesContext.getCurrentInstance().addMessage(null, message);
	}

	public void setCantidad(Integer cantidad) {
		this.cantidad = cantidad;
	}

	public void setCantidadFacturaCalculos(
			CantidadFactura cantidadFacturaCalculos) {
		this.cantidadFacturaCalculos = cantidadFacturaCalculos;
	}

	public void setCantidadFacturaPresentar(
			CantidadFactura cantidadFacturaPresentar) {
		this.cantidadFacturaPresentar = cantidadFacturaPresentar;
	}

	public void setCompModifica(String compModifica) {
		this.compModifica = compModifica;
	}

	public void setEgreso(Egreso egreso) {
		this.egreso = egreso;
	}

	public void setFacturaReporte(FacturaReporte facturaReporte) {
		this.facturaReporte = facturaReporte;
	}

	public void setFacturaReportes(List<FacturaReporte> facturaReportes) {
		this.facturaReportes = facturaReportes;
	}

	public void setListaFacturaReporteDevolucion(
			List<FacturaReporte> listaFacturaReporteDevolucion) {
		this.listaFacturaReporteDevolucion = listaFacturaReporteDevolucion;
	}

	// public void imprimirFactura() {
	// List<FacturaReporte> list = new ArrayList<FacturaReporte>();
	// for (int i = 0; i < egreso.getDetalleegresos().size(); i++)
	// list.add(egresoService.asignar(egreso.getDetalleegresos().get(i),
	// facturaReportes.get(i), 1, true));
	//
	// egresoReport.reporteFactura(egreso, clienteService
	// .obtenerPorPersonaId(cliente.getPersonaid().longValue()),
	// cantidadFacturaCalculos, list);
	// cancelarTodo();
	// }

	public void setProducto(Producto producto) {
		this.producto = producto;
	}

	private void xxx() {
		egreso = new Egreso();
		egreso.setLocal(new Local());
		// egreso.setVendedor(new Vendedor());
		egreso.setEntradas(new ArrayList<Entrada>());
		egreso.setDetalleegresos(new ArrayList<Detalleegreso>());
		egreso.setTipodocumento(null);
		egreso.setCodigodocumento(null);
	}

}